package net.lzzy.practices.services;

import net.lzzy.practices.entities.User;
import net.lzzy.practices.repositories.UserProjection;
import net.lzzy.practices.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {
    private final UserRepository repository;
    @Autowired
    public UserServiceImpl(UserRepository repository) {
        this.repository = repository;
    }

    /**
     * 登录时检查用户名密码是否正确
     *
     * @param userName 要检查用户名
     * @param password 对应密码
     * @return 检查正确则返回User对象，否则返回null
     */
    @Override
    public User check(String userName, String password) {
        return repository.findUserByUserNameAndPassword(userName, password);
    }

    /**
     * 根据用户名获取salt
     *
     * @param userName 要获取salt的用户名
     * @return salt
     */
    @Override
    public String getSalt(String userName) {
        List<UserProjection> users = repository.getUsersByUserName(userName);
        if (users == null || users.size() == 0){
            return "";
        }
        UserProjection user = users.get(0);
        String salt = user.getSalt();
        return salt== null?"":salt;
    }

    /**
     * 注册新用户
     *
     * @param user 前端传入的User对象
     * @return 注册成功返回注册User对象，否则返回null
     */
    @Override
    public User register(User user) {
        return repository.save(user);
    }

    /**
     * 检查用户名是否被占用
     *
     * @param userName 要检查的用户名
     * @return 用户名被占用返回true，否则返回false
     */
    @Override
    public Boolean isUserNameOccupied(String userName) {
        return repository.countByUserName(userName)>0;
    }

    /**
     * 获取所有用户
     *
     * @return 用户集合
     */
    @Override
    public List<User> get() {
        return repository.findAllByOrderByUpdateTimeDesc();
    }

    /**
     * 分页获取所有用户
     *
     * @param page 页码
     * @param size 每页数据大小
     * @return 用户集合
     */
    @Override
    public List<User> get(int page, int size) {
        return repository.findAllByOrderByUpdateTimeDesc(PageRequest.of(page,size));
    }

    /**
     * 统计用户总数
     *
     * @return 用户总数
     */
    @Override
    public Integer count() {
        return repository.countAllBy();
    }

    /**
     * 根据关键词搜索用户
     *
     * @param kw 查询关键词
     * @return 符合条件的用户集合
     */
    @Override
    public List<User> search(String kw) {
        return repository.findByQuery(kw);
    }


    /**
     * 根据申请状态获取用户
     *
     * @param applying true表示申请教师的用户
     * @return 符合条件的用户集合
     */
    @Override
    public List<User> getByApplyTeacher(boolean applying) {
        return repository.findUsersByApplyTeacherOrderByUpdateTimeDesc(applying);
    }

    /**
     * 审批通过教师资格
     * &#064;Transactional  演示
     * @param id 要审批的用户id
     * @return 审批成功返回User对象，否则返回null
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public User approveTeacher(UUID id) {
        User user =repository.findById(id).orElse(null);
        if (user!=null){
            user.setType(User.TYPE_TEACHER);
            user.setApplyTeacher(false);
            return repository.save(user);
        }

        return null;
    }

    /**
     * 审批不通过
     *
     * @param id 审批不通过的用户id
     * @return 审批成功返回User对象，否则返回null
     */
    @Override
    public User declineTeacher(UUID id) {
        User user =repository.findById(id).orElse(null);
        if (user!=null){
            user.setApplyTeacher(false);
            return repository.save(user);
        }
        return null;
    }

    /**
     * 禁止该用户登录
     *
     * @param id 要禁止的用户id
     * @return 禁止成功返回User对象，否则返回null
     */
    @Override
    public User banUser(UUID id) {
        User user =repository.findById(id).orElse(null);
        if (user!=null && user.getType() != User.TYPE_ADMIN){
            user.setType(User.TYPE_BANNED);
            return repository.save(user);
        }
        return null;
    }

    /**
     * 根据id获取用户
     *
     * @param id 要获取的用户id
     * @return 获取成功返回User对象，否则返回null
     */
    @Override
    public User getById(UUID id) {
        return repository.findById(id).orElse(null);
    }
}
